home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / m68k / cc68k.arc / REGISTER.C < prev    next >
C/C++ Source or Header  |  1986-10-26  |  5KB  |  164 lines

  1. #include        "stdio.h"
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7.  
  8. /*
  9.  *    68000 C compiler
  10.  *
  11.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  12.  *  all commercial rights reserved.
  13.  *
  14.  *    This compiler is intended as an instructive tool for personal use. Any
  15.  *    use for profit without the written consent of the author is prohibited.
  16.  *
  17.  *    This compiler may be distributed freely for non-commercial use as long
  18.  *    as this notice stays intact. Please forward any enhancements or question
  19. s
  20.  *    to:
  21.  *
  22.  *        Matthew Brandt
  23.  *        Box 920337
  24.  *        Norcross, Ga 30092
  25.  */
  26.  
  27. /*
  28.  *      this module handles the allocation and de-allocation of
  29.  *      temporary registers. when a temporary register is allocated
  30.  *      the stack depth is saved in the field deep of the address
  31.  *      mode structure. when validate is called on an address mode
  32.  *      structure the stack is popped until the register is restored
  33.  *      to it's pre-push value.
  34.  */
  35.  
  36. struct amode    push[] = { {am_adec,7} },
  37.                 pop[] = { {am_ainc,7} };
  38. int             next_data,
  39.                 next_addr;
  40. int             max_data,
  41.                 max_addr;
  42.  
  43.  gen_push(reg,rmode)
  44. /*
  45.  *      this routine generates code to push a register onto the stack
  46.  */
  47. int     reg, rmode;
  48. {       struct amode    *ap1;
  49.         ap1 =(struct amode *) xalloc(sizeof(struct amode));
  50.         ap1->preg = reg;
  51.         ap1->mode = rmode;
  52.         gen_code(op_move,4,ap1,push);
  53. }
  54.  
  55.  gen_pop(reg,rmode)
  56. /*
  57.  *      generate code to pop the primary register in ap from the
  58.  *      stack.
  59.  */
  60. int     reg, rmode;
  61. {       struct amode    *ap1;
  62.         ap1 =(struct amode *) xalloc(sizeof(struct amode));
  63.         ap1->preg = reg;
  64.         ap1->mode = rmode;
  65.         gen_code(op_move,4,pop,ap1);
  66. }
  67.  
  68.  initstack()
  69. /*
  70.  *      this routine should be called before each expression is
  71.  *      evaluated to make sure the stack is balanced and all of
  72.  *      the registers are marked free.
  73.  */
  74. {       next_data = 0;
  75.         next_addr = 0;
  76.         max_data = 2;
  77.         max_addr = 1;
  78. }
  79.  
  80.  validate(ap)
  81. /*
  82.  *      validate will make sure that if a register within an address
  83.  *      mode has been pushed onto the stack that it is popped back
  84.  *      at this time.
  85.  */
  86. struct amode    *ap;
  87. {       switch( ap->mode )
  88.                 {
  89.                 case am_direct:
  90.                 case am_immed:
  91.                         return;         /* no registers used */
  92.                 case am_dreg:
  93.                         if( ap->preg > 2 )
  94.                                 return; /* not a temporary */
  95.                         if( max_data - ap->deep >= 3 )
  96.                                 {
  97.                                 gen_pop(ap->preg,am_dreg);
  98.                                 --max_data;
  99.                                 }
  100.                         break;
  101.                 default:
  102.                         if( ap->preg > 1 )
  103.                                 return; /* not a temp register */
  104.                         if( max_addr - ap->deep >= 2 )
  105.                                 {
  106.                                 gen_pop(ap->preg,am_areg);
  107.                                 --max_addr;
  108.                                 }
  109.                         break;
  110.                 }
  111. }
  112.  
  113. struct amode    *temp_data()
  114. /*
  115.  *      allocate a temporary data register and return it's
  116.  *      addressing mode.
  117.  */
  118. {       struct amode    *ap;
  119.         ap =(struct amode *) xalloc(sizeof(struct amode));
  120.         ap->mode = am_dreg;
  121.         ap->preg = next_data % 3;
  122.         ap->deep = next_data;
  123.         if( next_data > max_data )
  124.                 {
  125.                 gen_push(next_data % 3,am_dreg);
  126.                 max_data = next_data;
  127.                 }
  128.         ++next_data;
  129.         return ap;
  130. }
  131.  
  132. struct amode    *temp_addr()
  133. /*
  134.  *      allocate a temporary address register and return it's
  135.  *      addressing mode.
  136.  */
  137. {       struct amode    *ap;
  138.         ap =(struct amode *) xalloc(sizeof(struct amode));
  139.         ap->mode = am_areg;
  140.         ap->preg = next_addr % 2;
  141.         ap->deep = next_addr;
  142.         if( next_addr > max_addr )
  143.                 {
  144.                 gen_push(next_addr % 2,am_areg);
  145.                 max_addr = next_addr;
  146.                 }
  147.         ++next_addr;
  148.         return ap;
  149. }
  150.  
  151.  freeop(ap)
  152. /*
  153.  *      release any temporary registers used in an addressing mode.
  154.  */
  155. struct amode    *ap;
  156. {       if( ap->mode == am_immed || ap->mode == am_direct )
  157.                 return;         /* no registers used */
  158.         if( ap->mode == am_dreg && ap->preg < 3 )
  159.                 --next_data;
  160.         else if( ap->preg < 2 )
  161.                 --next_addr;
  162. }
  163.  
  164.